home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d15
/
hex.arc
/
HEX.C
next >
Wrap
Text File
|
1991-02-26
|
31KB
|
980 lines
/*----------------------------------------------------------
HEX.C -- File Hex Dump Program
(c) Kamyar Goodarzi & Jim Boyce, 1990
----------------------------------------------------------*/
#include <windows.h>
#include <string.h>
#include <math.h>
#include <sys\types.h>
#include <sys\stat.h>
#include "hex.h"
// the following function prints the last file line if it is less than
// 16 bytes. I took the easy way out and used the sprintf to create
// the last file line string.
void GetLastString (LONG lFileOffsetTmp, unsigned char *pBuffer) {
int i, j, c ;
c = (count % 16) ;
sprintf (printStr, "%.8lX ", lFileOffsetTmp) ;
for (i = 0, j = 10 + 3 * c; i <= 16 - c; i++, j +=3)
sprintf ((printStr + j), " ") ;
for (i = 0, j = 10; i < c; i++, j += 3, pBuffer++) {
sprintf ((printStr + j), " %.2X", *pBuffer) ;
sprintf ((printStr + 61 + i), "%c", *pBuffer) ;
}
*(printStr + j) = ' ' ;
strLength = 61 + c ;
}
// Reads characters from the user-selected file and fills a file buffer.
void FillBuff (HWND hwnd) {
// Sets cursor to hourglass.
hSaveCursor = SetCursor (hHourGlass) ;
// Reopens the file and in the case of errors, displays an appropriate
// message (if there is a file-open error, Hex Dump terminates).
if ((hFile = OpenFile ((LPSTR) NULL, &OFStruct, OF_REOPEN | OF_READ)) < 0) {
sprintf (str, "Error %d opening %s.", OFStruct.nErrCode, OpenName) ;
MessageBox (hwnd, (LPSTR) str, NULL, MB_OK | MB_ICONHAND) ;
SendMessage (hwnd, WM_DESTROY, 0, 0L) ;
return ;
}
// Calculates the actual file offset.
lFileOffset = lFileLine * 16 ;
// Positions the file pointer to the previously calculated file offset.
if ((lFileOffset = _llseek (hFile, lFileOffset, 0)) == -1) {
sprintf (str, "Error reading %s.", FileName) ;
MessageBox (hwnd, (LPSTR) str, NULL, MB_OK | MB_ICONHAND) ;
SendMessage (hwnd, WM_DESTROY, 0, 0L) ;
return ;
}
// Fills the buffer by reading from the file.
if ((count = _lread (hFile, (LPSTR) pFileBuf, FOURKBYTE)) == -1) {
sprintf (str, "Error reading %s.", FileName) ;
MessageBox (hwnd, (LPSTR) str, NULL, MB_OK | MB_ICONHAND) ;
SendMessage (hwnd, WM_DESTROY, 0, 0L) ;
return ;
}
// If the amount read is less than the size of the buffer, end of
// file is set TRUE. Otherwise, end of file is FALSE.
if (count < FOURKBYTE)
endOfFile = TRUE ;
else
endOfFile = FALSE ;
// Calculate the number of lines inside the buffer.
nBufLines = (int) ceil ((double) count / 16.0) ;
// Close the file.
_lclose (hFile) ;
}
/*-------------------------------------------------------------------
Hex Main Windows procedure
-------------------------------------------------------------------*/
int PASCAL WinMain (HANDLE hInstance,
HANDLE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow) {
HWND hwnd ;
MSG msg ;
WNDCLASS wndClass ;
if (!hPrevInstance) {
wndClass.style = CS_HREDRAW | CS_VREDRAW ;
wndClass.lpfnWndProc = WndProc ;
wndClass.cbClsExtra = 0 ;
wndClass.cbWndExtra = 0 ;
wndClass.hInstance = hInstance ;
wndClass.hIcon = LoadIcon (hInstance, "Hex") ;
wndClass.hCursor = LoadCursor (hInstance, "Hex") ;
wndClass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
wndClass.lpszMenuName = "Hex" ;
wndClass.lpszClassName = "Hex" ;
RegisterClass (&wndClass) ;
}
hInst = hInstance ;
hHexMenu = LoadMenu (hInstance, "Hex") ;
lpHexTitle = lstrcpy ((LPSTR) str, "Hex Dump") ;
hwnd = CreateWindow (
"Hex",
lpHexTitle,
WS_OVERLAPPEDWINDOW |
WS_VSCROLL |
WS_HSCROLL,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
hHexMenu,
hInstance,
NULL) ;
if (!hwnd)
return (FALSE) ;
ShowWindow (hwnd, nCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
long FAR PASCAL WndProc (HWND hwnd,
unsigned message,
WORD wParam,
LONG lParam) {
unsigned char *p ;
HDC hdc ;
LONG lFileOffsetTmp, lScrollPos ;
short i, x, y, nPaintBeg, nPaintEnd, nScrollInc ;
DWORD lParameter ;
PAINTSTRUCT ps ;
TEXTMETRIC tm ;
FARPROC lpOpenDlg ;
FARPROC lpProcAbout ;
switch (message) {
case WM_CREATE :
// Get device context so object can be selected based
// on the device.
hdc = GetDC (hwnd) ;
// Get system fixed font for calculating character height
// and width.
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
GetTextMetrics (hdc, &tm) ;
nCharWidth = tm.tmAveCharWidth ;
nCharHeight = tm.tmHeight + tm.tmExternalLeading ;
// Release the device context.
ReleaseDC (hwnd, hdc) ;
return (FALSE);
case WM_COMMAND :
switch (wParam) {
case IDM_ABOUT :
// if user picks the About menu item.
// use the WinAboutProc window procedure instead of
// the WndProc.
lpProcAbout = MakeProcInstance (WinAboutProc, hInst) ;
// display the dialogue box.
DialogBox (hInst,
"AboutBox",
hwnd,
lpProcAbout) ;
// set the window procedure back to WndProc.
FreeProcInstance (lpProcAbout) ;
// skip the remaining cases.
break ;
case IDM_EXIT :
// free the memory that was allocated to the file
// buffer.
hFileBuf = LocalFree (hFileBuf) ;
// if encounter any errors display a message and quit
// the application.
if (hFileBuf) {
MessageBox (hwnd,
"Memory error. Terminating the program.",
NULL, MB_OK | MB_ICONHAND) ;
}
SendMessage (hwnd, WM_DESTROY, 0, 0L) ;
break ;
case IDM_HELP :
// if user selects help menu item, use the WinHelp
// function to display contents of hex.hlp.
WinHelp (hwnd, "HEX.HLP", HELP_INDEX, NULL) ;
break ;
case IDM_CLOSE :
// user selects the close menu item.
// set file handle to 0 (no file is currently open).
hFile = 0 ;
// give up the allocated memory. if any errors
// display a message and terminate the application.
hFileBuf = LocalFree (hFileBuf) ;
if (hFileBuf) {
MessageBox (hwnd,
"Memory error. Terminating the program.",
NULL, MB_OK | MB_ICONHAND) ;
SendMessage (hwnd, WM_DESTROY, 0, 0L) ;
}
// gray (disable) the close menu item.
EnableMenuItem (hHexMenu, IDM_CLOSE, MF_GRAYED) ;
// strip the file name from the title and display
// it in the title bar.
lpHexTitle = lstrcpy ((LPSTR) str, "Hex Dump") ;
SetWindowText (hwnd, lpHexTitle) ;
// clear the entir client area and repaint.
InvalidateRect (hwnd, NULL, TRUE) ;
// Build the low and high words of the message
// parameter.
lParameter = ((DWORD) nClientHeight << 16) |
nClientWidth ;
// send the above calculated parameter as part of the
// WM_SIZE message.
SendMessage (hwnd, WM_SIZE, SIZENORMAL, lParameter) ;
break ;
case IDM_OPEN :
// if the file buffer handle is 0 (no previously
// allocated memory), allocated memory for the
// file buffer. if an error was encountered, display
// an error message return.
if (!hFileBuf)
if ((hFileBuf = LocalAlloc (LMEM_MOVEABLE, FOURKBYTE+16)) == NULL) {
MessageBox (hwnd, "Not Enough Memory.", NULL, MB_OK | MB_ICONHAND) ;
return FALSE ;
}
// setup the OpenDlg window procedure to service
// the needs of the dialogue box.
lpOpenDlg = MakeProcInstance (
(FARPROC) OpenDlg, hInst) ;
DialogBox (hInst, "Open", hwnd, lpOpenDlg) ;
// let WndProc window procedure handle windows messages.
FreeProcInstance (lpOpenDlg) ;
// if a file was not opened, return from this procedure.
if (!hFile)
return FALSE ;
// enable the Close menu item.
EnableMenuItem (hHexMenu, IDM_CLOSE, MF_ENABLED) ;
// obtain the file stauts (size ...). File attributes
// will be written in the FileStatus structure.
fstat (hFile, &FileStatus) ;
// calculate the total number of linse in that file.
lTotalFileLines = (LONG) ceil ((double)
FileStatus.st_size / 16.0) ;
// display the file size and name in the title bar.
sprintf (printStr, " [%.8lX] hex Bytes", FileStatus.st_size) ;
lpHexTitle = lstrcat (lstrcat (lstrcpy ((LPSTR) str, "Hex Dump -- "),
(LPSTR) OpenName), (LPSTR) printStr) ;
SetWindowText (hwnd, lpHexTitle) ;
// calculate the number of file lines per scroll bar
// increment.
if (lTotalFileLines > MAXINT)
nNumOfLines = MAXINT ;
else
nNumOfLines = (int) ceil ((double) FileStatus.st_size
/ 16.0) ;
// set the file offset and the file line offset to start (0).
// set the cursor to the hourglass, use LocalLock to obtain
// a pointer to the file buffer.
// read 4K bytes into the buffer. close the file
// set cursor back to mouse.
lFileOffset = 0L ;
lFileLine = 0L ;
hSaveCursor = SetCursor (hHourGlass) ;
pFileBuf = LocalLock (hFileBuf) ;
nWinFirstLine = 0 ;
count = _lread (hFile, (LPSTR) pFileBuf, FOURKBYTE) ;
_lclose (hFile) ;
SetCursor (hSaveCursor) ;
// if the _lread function return value is equal to -1 (error),
// display an error message and return.
if (count == -1) {
sprintf (str, "Error reading %s.", FileName) ;
MessageBox (hwnd, (LPSTR) str, NULL,
MB_OK | MB_ICONHAND) ;
return (FALSE) ;
}
// if count is less than the buffer size, set end of file
// flag to TRUE; otherwise set to FALSE.
if (count < FOURKBYTE)
endOfFile = TRUE ;
else
endOfFile = FALSE ;
// calculate number of the file lines present in the
// buffer, and release the buffer pointer.
nBufLines = ceil ((double) count / 16.0) ;
LocalUnlock (hFileBuf) ;
// Clear the client area for repaint.
InvalidateRect (hwnd, NULL, TRUE) ;
// reset the scroll bar position to 0.
nVSBarPos = 0 ;
// Build the low and high words of the message
// parameter.
lParameter = ((DWORD) nClientHeight << 16) |
nClientWidth ;
// send the above calculated parameter as part of the
// WM_SIZE message.
SendMessage (hwnd, WM_SIZE, SIZENORMAL, lParameter) ;
}
return FALSE ;
case WM_SIZE :
// calculate the client area's width and height and the number
// of lines that can fit in that area.
nClientWidth = LOWORD (lParam) ;
nClientHeight = HIWORD (lParam) ;
nWinLines = nClientHeight / nCharHeight ;
// this section adds/removes scroll bars depending on the
// size of client area and adjusts the scroll bar position.
// this is only done if a file is open. when files are closed
if(hFile) {
if (nWinLines >= nNumOfLines)
nVSBarMax = 0 ;
else
nVSBarMax = nNumOfLines + 4 -nWinLines ;
nVSBarPos = min (nVSBarPos, nVSBarMax) ;
nHSBarMax = max (0,2 + (79 * nCharWidth - nClientWidth) / nCharWidth) ;
nHSBarPos = min (nHSBarPos, nHSBarMax) ;
}
else {
nVSBarMax = nVSBarPos = nHSBarMax = nHSBarPos = 0 ;
}
// set the vertical scroll bar's max value and position.
SetScrollRange (hwnd, SB_VERT, 0, nVSBarMax, FALSE) ;
SetScrollPos (hwnd, SB_VERT, nVSBarPos, TRUE) ;
// set the horizontal scroll bar's max value and position.
SetScrollRange (hwnd, SB_HORZ, 0, nHSBarMax, FALSE) ;
SetScrollPos (hwnd, SB_HORZ, nHSBarPos, TRUE) ;
return FALSE ;
// Service all vertical scroll messages.
case WM_VSCROLL :
// calculate the temporary scroll/file position.
lScrollPos = lFileLine + nWinFirstLine ;
switch (wParam) {
case SB_TOP :
lScrollPos = 0L ;
break ;
case SB_BOTTOM :
lScrollPos = lTotalFileLines - nWinLines ;
break ;
case SB_LINEUP :
if (lScrollPos != 0) {
lScrollPos -= 1 ;
}
break ;
case SB_LINEDOWN :
if (lScrollPos < lTotalFileLines - nWinLines) {
lScrollPos = lFileLine + nWinFirstLine + 1 ;
}
break ;
case SB_PAGEUP :
if (lScrollPos > 0) {
lScrollPos = lFileLine + nWinFirstLine + min (-1, -nWinLines) ;
if (lScrollPos < 0)
lScrollPos = 0 ;
}
break ;
case SB_PAGEDOWN :
if (lScrollPos >= lTotalFileLines - 2 * nWinLines)
lScrollPos = lTotalFileLines - nWinLines ;
else
lScrollPos = lFileLine + nWinFirstLine + max (1, nWinLines) ;
break ;
case SB_THUMBPOSITION :
// if the thumbposition has changed do the following.
if (LOWORD (lParam) != nVSBarPos) {
// if set to the end of the file and less than
// one page displayed, set the temp. file pointer
// to then end of file minus a screen full.
if (LOWORD (lParam) >= nNumOfLines - nWinLines)
lScrollPos = lTotalFileLines - nWinLines ;
else
// else calculate the new file position.
lScrollPos = (LONG) ceil (((double)LOWORD (lParam)) *
((double) lTotalFileLines / (double) nNumOfLines)) ;
}
}
// if lScrollPos is changed do the following:
if (lScrollPos != lFileLine + nWinFirstLine) {
// obtain a pointer to the local buffer memory.
pFileBuf = LocalLock (hFileBuf) ;
// if the scroll amount is than a client area full, scroll
// the window, otherwise clear it and repaint.
if ((labs (lScrollPos - (lFileLine
+ nWinFirstLine))) < (LONG) nWinLines)
ScrollWindow (hwnd, 0, -nCharHeight *
(int) (lScrollPos -
(lFileLine + nWinFirstLine))
, NULL, NULL) ;
else
InvalidateRect (hwnd, NULL, TRUE) ;
// calculate the new vertical scroll position.
nVSBarPos = (int) ceil (((double) lScrollPos /
(double) lTotalFileLines) * nNumOfLines) ;
// report the new vertical position to windows.
SetScrollPos (hwnd, SB_VERT, nVSBarPos, TRUE) ;
// if the new file pointer is less than the current, read
// a buffer full and set the windows first line offset to
// 0.
if (lScrollPos < lFileLine) {
lFileLine = lScrollPos ;
nWinFirstLine = 0 ;
FillBuff (hwnd) ;
}
else {
// if the new file pointer is greater than the current
// and does not land in the file buffer area do the
// following.
if(lScrollPos > lFileLine + nBufLines + 1 - nWinLines) {
// if it is not the end of file adjust the current
// file pointer and fill the buffer with data.
if (!endOfFile) {
lFileLine = lScrollPos ;
nWinFirstLine = 0 ;
FillBuff (hwnd) ;
}
else
// else adjust the offset of the first line
// in the client area.
nWinFirstLine = (int) (nBufLines - nWinLines) ;
}
else
// if the new file pointer lands in the buffer
// then adjust offset of the first line in the
// client area.
nWinFirstLine = (int) (lScrollPos - lFileLine) ;
}
// update the client area and release the buffer memory
// pointer.
UpdateWindow (hwnd) ;
LocalUnlock (hFileBuf) ;
}
return FALSE ;
case WM_HSCROLL :
switch (wParam) {
case SB_LINEUP :
nScrollInc = -1 ;
break ;
case SB_LINEDOWN :
nScrollInc = 1 ;
break ;
case SB_PAGEUP :
nScrollInc = -5 ;
break ;
case SB_PAGEDOWN :
nScrollInc = 5 ;
break ;
case SB_THUMBTRACK :
nScrollInc = LOWORD (lParam) - nHSBarPos ;
break ;
default :
nScrollInc = 0 ;
}
// use the user horizontal scroll request to calculate
// the new horizontal scroll position and the contents of the
// client area.
if (nScrollInc = max (-nHSBarPos,
min (nScrollInc, nHSBarMax - nHSBarPos))) {
nHSBarPos += nScrollInc ;
ScrollWindow (hwnd, -nCharWidth * nScrollInc, 0, NULL, NULL) ;
SetScrollPos (hwnd, SB_HORZ, nHSBarPos, TRUE) ;
}
return FALSE ;
case WM_KEYDOWN :
switch (wParam) {
case VK_HOME :
SendMessage (hwnd, WM_VSCROLL, SB_TOP, 0L) ;
break ;
case VK_END :
SendMessage (hwnd, WM_VSCROLL, SB_BOTTOM, 0L) ;
break ;
case VK_PRIOR :
SendMessage (hwnd, WM_VSCROLL, SB_PAGEUP, 0L) ;
break ;
case VK_NEXT :
SendMessage (hwnd, WM_VSCROLL, SB_PAGEDOWN, 0L) ;
break ;
case VK_UP :
SendMessage (hwnd, WM_VSCROLL, SB_LINEUP, 0L) ;
break ;
case VK_DOWN :
SendMessage (hwnd, WM_VSCROLL, SB_LINEDOWN, 0L) ;
break ;
case VK_LEFT :
SendMessage (hwnd, WM_HSCROLL, SB_PAGEUP, 0L) ;
break ;
case VK_RIGHT :
SendMessage (hwnd, WM_HSCROLL, SB_PAGEDOWN, 0L) ;
break ;
}
return FALSE ;
case WM_PAINT :
// obtain a device context handle and the attributes of the
// paint area using the BeginPaint function.
hdc = BeginPaint (hwnd, &ps) ;
// do the following block only if a file is open, since the
// client area will be blank otherwise.
if (hFile) {
// obtain a pointer to the allocated memory block using
// the LocalLock function.
pFileBuf = LocalLock (hFileBuf) ;
// use the system fixed font.
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
// calculate the begin and end of the invalid client area.
// the invalid client area is the area that must be
// repainted.
nPaintBeg = max (0, ps.rcPaint.top / nCharHeight -1) ;
nPaintEnd = ps.rcPaint.bottom / nCharHeight ;
// calculate the leftmost character based on the
// horizontal scroll bar position.
x = nCharWidth * (1 - nHSBarPos) ;
// obtain a pointer to the next line to be displayed
// within the new paint area.
p = nWinFirstLine * 16 + pFileBuf + (nPaintBeg * 16) ;
// calculate the file position (byte value) for each line.
lFileOffsetTmp = ((lFileLine + nWinFirstLine) * 16)
+ (nPaintBeg * 16) ;
// while in paint area, and not outside the buffer:
// from top of paint area to end of paint area, paint
// the file offset, byte value, and ASCII string.
for (i = nPaintBeg; i <= nPaintEnd && p < pFileBuf + count;
i++, p += 16, lFileOffsetTmp += 16) {
// calculate vertical position of the first line
// of the paint area.
y = nCharHeight * i ;
// if end of file and the last line is less than
// 16 bytes use the GetLastString to obtain the
// last file line.
if (endOfFile && (pFileBuf + count - p < 16) &&
count % 16)
GetLastString (lFileOffsetTmp, p) ;
else
// otherwise use sprintf to print 16 byte to a
// string.
strLength = sprintf (printStr, formatString,
lFileOffsetTmp, *(p+0), *(p+1), *(p+2), *(p+3), *(p+4),
*(p+5), *(p+6), *(p+7), *(p+8), *(p+9), *(p+10),
*(p+11), *(p+12), *(p+13), *(p+14), *(p+15),
*(p+0), *(p+1), *(p+2), *(p+3), *(p+4),
*(p+5), *(p+6), *(p+7), *(p+8), *(p+9), *(p+10),
*(p+11), *(p+12), *(p+13), *(p+14), *(p+15)) ;
// display the string in the client area.
TextOut (hdc, x, y, (LPSTR) printStr, strLength) ;
}
// release the file buffer pointer.
LocalUnlock (hFileBuf) ;
}
// end paint.
EndPaint (hwnd, &ps) ;
return FALSE ;
case WM_DESTROY :
// to end application execution, free the allocated memory
// and post a quit message.
LocalFree (hFileBuf) ;
PostQuitMessage (0) ;
return FALSE ;
}
// All messages not processed by this procedure, including system
// messages, are passed to DefWindowProc.
return (DefWindowProc (hwnd, message, wParam, lParam)) ;
}
/*-----------------------------------------------------------------------
The Window Procedure for About dialog box. Dialog functions must
service user inputs only.
-----------------------------------------------------------------------*/
BOOL FAR PASCAL WinAboutProc (HWND hDlg,
unsigned message,
WORD wParam,
LONG lParam)
{
switch (message) {
case WM_INITDIALOG : // return TRUE to initialize
// the box. This will pass
return (TRUE) ; // the focus to the
// default push button.
case WM_COMMAND :
switch (wParam) {
case IDOK : // if user input is OK or
case IDCANCEL : // cancel, end the dialog.
EndDialog (hDlg, TRUE) ;
return TRUE ;
}
}
return (FALSE) ;
}
/*-----------------------------------------------------------------------
The remaining of this program has been taken from examples in the
Microsoft (R) Windows Guide to Programming book. This section of the
code opens the file dialogue box, assists the controls in the dialogue
box to display directories, filenames, etc. It also opens the file
selected by the user.
-----------------------------------------------------------------------*/
void UpdateListBox (HWND hDlg) {
strcpy (str, DefPath) ;
strcat (str, DefSpec) ;
DlgDirList (hDlg, str, IDC_LISTBOX, IDC_PATH, 0x4010) ;
SetDlgItemText (hDlg, IDC_EDIT, DefSpec) ;
}
void SeparateFile (HWND hDlg,
LPSTR lpDestPath,
LPSTR lpDestFileName,
LPSTR lpSrcFileName) {
LPSTR lpTmp ;
char cTmp ;
lpTmp = lpSrcFileName + (long) lstrlen (lpSrcFileName) ;
while (*lpTmp != ':' && *lpTmp != '\\' && lpTmp > lpSrcFileName)
lpTmp = AnsiPrev (lpSrcFileName, lpTmp) ;
if (*lpTmp != ':' && *lpTmp != '\\') {
lstrcpy (lpDestFileName, lpSrcFileName) ;
lpDestPath[0] = 0 ;
return ;
}
lstrcpy (lpDestFileName, lpTmp + 1) ;
cTmp = *(lpTmp + 1) ;
lstrcpy (lpDestPath, lpSrcFileName) ;
*(lpTmp + 1) = cTmp ;
lpDestPath [(lpTmp - lpSrcFileName) + 1] = 0 ;
}
void ChangeDefExt (PSTR Ext, PSTR Name) {
PSTR pTptr ;
pTptr = Name ;
while (*pTptr && * pTptr != '.')
pTptr++ ;
if (*pTptr)
if (!strchr (pTptr, '*') && !strchr (pTptr, '?'))
strcpy (Ext, pTptr) ;
}
void AddExt (PSTR Name, PSTR Ext) {
PSTR pTptr ;
pTptr = Name ;
while (*pTptr && *pTptr != '.')
pTptr++ ;
if (*pTptr != '.')
strcat (Name, Ext) ;
}
HANDLE FAR PASCAL OpenDlg (HWND hDlg,
unsigned message,
WORD wParam,
LONG lParam) {
WORD index ;
PSTR pTptr ;
switch (message) {
case WM_COMMAND :
switch (wParam) {
case IDC_LISTBOX :
switch (HIWORD (lParam)) {
case LBN_SELCHANGE :
if (!DlgDirSelect (hDlg, str, IDC_LISTBOX)) {
SetDlgItemText (hDlg, IDC_EDIT, str) ;
SendDlgItemMessage (hDlg, IDC_EDIT,
EM_SETSEL,
NULL,
MAKELONG (0, 0x7fff)) ;
}
else {
strcat (str, DefSpec) ;
DlgDirList (hDlg, str, IDC_LISTBOX,
IDC_PATH, 0x4010) ;
}
break ;
case LBN_DBLCLK :
goto openFile ;
}
return (TRUE) ;
case IDOK :
openFile:
GetDlgItemText (hDlg, IDC_EDIT, OpenName, 128) ;
if (strchr (OpenName, '*') || strchr (OpenName, '?')) {
SeparateFile (hDlg, (LPSTR) str,
(LPSTR) DefSpec,
(LPSTR) OpenName) ;
if (str[0])
strcpy (DefPath, str) ;
ChangeDefExt (DefExt, DefSpec) ;
UpdateListBox (hDlg) ;
return (TRUE) ;
}
if (!OpenName[0]) {
MessageBox (hDlg, "No filename specified.",
NULL, MB_OK | MB_ICONQUESTION) ;
return (TRUE) ;
}
if ((hFile = OpenFile (OpenName, (LPOFSTRUCT) &OFStruct,
OF_READ)) < 0) {
sprintf (str, "Error %d opening %s.",
OFStruct.nErrCode, OpenName) ;
MessageBox (hDlg, (LPSTR) str, NULL, MB_OK | MB_ICONHAND) ;
}
else {
strcpy (FileName, OpenName) ;
EndDialog (hDlg, hFile) ;
return (FALSE) ;
}
case IDCANCEL :
EndDialog (hDlg, NULL) ;
hFile = 0 ;
return (FALSE) ;
}
break ;
case WM_INITDIALOG :
UpdateListBox (hDlg) ;
SetDlgItemText (hDlg, IDC_EDIT, DefSpec) ;
SendDlgItemMessage (hDlg,
IDC_EDIT,
EM_SETSEL,
NULL,
MAKELONG (0, 0x7fff)) ;
SetFocus (GetDlgItem (hDlg, IDC_EDIT)) ;
return (FALSE) ;
}
return (FALSE) ;
}